﻿using UnityEngine;
using System.Collections;

namespace net {
	public class NetAI : MonoBehaviour {

		// 坦克移动速度
		float speed = 5f;
		//坦克的护甲
		public int armor = 0;
		//tank 等级
		public int level = 1;
		// 配置数据
		Config cfg = new Config ();
		SpeedCfg speedcfg = new SpeedCfg();
		// 方向 1234 ~ 上下左右
		int direction = 1;	// 默认向上
		// 炮弹初始位置偏移量
		float bulletOffset = 1.5f;
		// 自动移动CD
		float moveClodDown = 0.7f;
		// 自动开火CD
		float fireClodDown = 1f;
		// 控制CD
		float time;
		float lastMove;
		float lastFire;
		//控制惯性时间
		float preTime; 
		
		Vector2 UP = new Vector2(0, 1);
		Vector2 DOWN = new Vector2(0, -1);
		Vector2 LEFT = new Vector2(-1, 0);
		Vector2 RIGHT = new Vector2(1, 0);
		
		Vector3 pos;
		NetAIState aiState;
		
		// Use this for initialization
		void Start () {
			aiState = GetComponent<NetAIState> ();
		}
		
		// Update is called once per frame
		void Update () {
			time = Time.time;
			pos = transform.position;
			
			// 死了不能动不能打
			if (!aiState.isAlive) {
				return;
			}
			if(aiState.hasInertia){
				autoRun();
				return;
			}
			
			randMove();
			//Cd没好不让打
			if(!aiState.readyToFire){
				return;
			}
			randFire ();
		}
		
		void randMove() {
			
			if (lastMove == 0 || (time > moveClodDown + lastMove)) {
				direction = Common.rand (-2,2);
				if(direction==0){
					direction = Common.UP;
				}
				lastMove = Time.time;
			}
			
			move ();
		}
		
		void randFire() {
			bool readyToFire = Common.rand (0, 1) == 1; 
			
			if (lastMove == 0 || (time > fireClodDown + lastFire) && readyToFire) {
				fire ();
				lastFire = Time.time;
			}
		}
		
		void move () {
			//------ 移动
			if (direction == Common.LEFT) {
				// 向左移动
				if (canMove(Common.LEFT)) {
					transform.position = new Vector3(pos.x - Time.deltaTime * speed, pos.y, pos.z);
				}
				// 转向
				transform.rotation = Quaternion.Euler(new Vector3(0, 0, 90));
				direction = Common.LEFT;
			}
			else if (direction == Common.RIGHT) {				
				// 向右移动
				if (canMove(Common.RIGHT)) {
					transform.position = new Vector3(pos.x + Time.deltaTime * speed, pos.y, pos.z);
				}
				// 转向
				transform.rotation = Quaternion.Euler(new Vector3(0, 0, 270));
				direction = Common.RIGHT;
			}
			else if (direction == Common.UP) {
				// 向上移动
				if (canMove(Common.UP)) {
					transform.position = new Vector3(pos.x, pos.y + Time.deltaTime * speed, pos.z);
				}
				// 转向
				//!!! 角度逆时针为正
				transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0));
				direction = Common.UP;
			}
			else if (direction == Common.DOWN) {
				// 向下移动
				if (canMove(Common.DOWN)) {
					transform.position = new Vector3(pos.x, pos.y - Time.deltaTime * speed, pos.z);
				}
				// 转向
				transform.rotation = Quaternion.Euler(new Vector3(0, 0, 180));
				direction = Common.DOWN;
			}
			//------ end 移动
		}
		
		void fire () {
			Vector3 pos = transform.position;
			
			//------ 开火
			Vector3 bulletPos = Vector3.zero;
			
			if (direction == Common.UP) {
				bulletPos = new Vector3(pos.x, pos.y + bulletOffset, pos.z);
			}
			else if (direction == Common.DOWN) {
				bulletPos = new Vector3(pos.x, pos.y - bulletOffset, pos.z);
			}
			else if (direction == Common.LEFT) {
				bulletPos = new Vector3(pos.x - bulletOffset, pos.y, pos.z);
			}
			else if (direction == Common.RIGHT) {
				bulletPos = new Vector3(pos.x + bulletOffset, pos.y, pos.z);
			}
			

			GetComponent<NetBullet>().NewBomb(direction, bulletPos,gameObject,false);
			aiState.readyToFire = false;
			//------ end 开火
		}
		
		public bool canMove (int direction) {
			float rayOffset = 0.2f;
			float distance = 0.1f;
			
			bool res = true;
			GameObject[] objs = null;
			
			if (direction == Common.LEFT) {
				objs = objsDetect(new Vector2(pos.x - 1, pos.y + 1 - rayOffset),
				                  new Vector2(pos.x - 1, pos.y - 1 + rayOffset),
				                  LEFT,
				                  distance
				                  );
			}
			else if (direction == Common.RIGHT) {
				objs = objsDetect(new Vector2(pos.x + 1, pos.y + 1 - rayOffset),
				                  new Vector2(pos.x + 1, pos.y - 1 + rayOffset),
				                  RIGHT,
				                  distance
				                  );
			}
			else if (direction == Common.UP) {
				objs = objsDetect(new Vector2(pos.x - 1 + rayOffset, pos.y + 1),
				                  new Vector2(pos.x + 1 - rayOffset, pos.y + 1),
				                  UP,
				                  distance
				                  );
			}
			else if (direction == Common.DOWN) {
				objs = objsDetect(new Vector2(pos.x - 1 + rayOffset, pos.y - 1),
				                  new Vector2(pos.x + 1 - rayOffset, pos.y - 1),
				                  DOWN,
				                  distance
				                  );
			}
			
			for (int i = 0; i < objs.Length; i++) {
				if (!canPass(objs[i])) {
					res = false;
				}
			}
			
			float preSpeed = speed;
			speed = speedcfg.getSpeed(objs);
			if(preSpeed>speed &&(speedcfg.getSpeed("snow")== preSpeed)){ 
				aiState.hasInertia = true;
				preTime = Time.time;
			}
			
			return res;
		}
		
		bool canPass(GameObject obj) {
			string objName;
			bool res = true;
			
			if (obj != null) {
				objName = Common.getObjName (obj);
				res = cfg.canTankPass (objName);
			}
			
			return res;
		}
		
		GameObject[] objsDetect(Vector2 start, Vector2 end, Vector2 direction, float distance) {
			GameObject[] objs = new GameObject[7];
			
			// start
			objs[0] = rayDetect(start, direction, distance);
			// end
			objs[1] = rayDetect(end, direction, distance);
			
			// 中间
			if (LEFT.Equals (direction) || RIGHT.Equals(direction)) {
				objs[2] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2), direction, distance);
				objs[3] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2 - 0.3f), direction, distance);
				objs[4] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2 - 0.6f), direction, distance);
				objs[5] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2 + 0.3f), direction, distance);
				objs[6] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2 + 0.6f), direction, distance);
			}
			else if (UP.Equals (direction) || DOWN.Equals(direction)) {
				objs[2] = rayDetect(new Vector2((start.x + end.x) / 2, start.y), direction, distance);
				objs[3] = rayDetect(new Vector2((start.x + end.x) / 2 - 0.3f, start.y), direction, distance);
				objs[4] = rayDetect(new Vector2((start.x + end.x) / 2 - 0.6f, start.y), direction, distance);
				objs[5] = rayDetect(new Vector2((start.x + end.x) / 2 + 0.3f, start.y), direction, distance);
				objs[6] = rayDetect(new Vector2((start.x + end.x) / 2 + 0.6f, start.y), direction, distance);
			}
			
			return objs;
		}
		
		// 射线检测
		GameObject rayDetect(Vector2 start, Vector2 direction, float distance) {
			GameObject obj = null;
			RaycastHit2D hit = Physics2D.Raycast(start, direction, distance, 1 << LayerMask.NameToLayer("Default"));
			
			//	Debug.DrawLine(new Vector3(start.x, start.y, 0), new Vector3(start.x, start.y + distance, 0), Color.red, 3f);
			
			if (hit.collider != null) {
				obj = hit.collider.gameObject;
			}
			
			return obj;
		}
		
		void autoRun(){
			float time = Time.time;
			if(time>preTime + SpeedCfg.inertiaTime){
				aiState.hasInertia = false;
				return;
			}
			if(direction == Common.LEFT){
				if (canMove(Common.LEFT)) {
					transform.position = new Vector3(pos.x - Time.deltaTime * speed, pos.y, pos.z);
				}
			}
			if(direction == Common.RIGHT){
				if (canMove(Common.RIGHT)) {
					transform.position = new Vector3(pos.x + Time.deltaTime * speed, pos.y, pos.z);
				}
			}
			
			if(direction == Common.UP){
				if (canMove(Common.UP)) {
					transform.position = new Vector3(pos.x, pos.y + Time.deltaTime * speed, pos.z);
				}
			}
			
			if(direction == Common.DOWN){
				if (canMove(Common.DOWN)) {
					transform.position = new Vector3(pos.x, pos.y - Time.deltaTime * speed, pos.z);
				}
			}
		}
		
		void OnNetworkInstantiate(NetworkMessageInfo info){
			if(!networkView.isMine){
				gameObject.GetComponent<NetAI>().enabled = false;
				gameObject.GetComponent<NetAIState>().enabled = false;
			}
		}

		void OnDestroy(){
			Vector3 currentpos = gameObject.transform.position;
			if(networkView.isMine){
				switch(level){
				case 1: Network.Instantiate(Resources.Load("prefab/wuzi25"),currentpos,Quaternion.identity,0);break;
				case 2: Network.Instantiate(Resources.Load("prefab/wuzi40"),currentpos,Quaternion.identity,0);break;
				case 3: Network.Instantiate(Resources.Load("prefab/wuzi50"),currentpos,Quaternion.identity,0);break;
				case 4: Network.Instantiate(Resources.Load("prefab/wuzi40"),currentpos,Quaternion.identity,0);break;
				}
			}
		}
	}
}